筆者有以下分析需求
這邊可以使用 Azure Retail Prices REST API 達到目的
Azure 上取得服務單價資料方式只有一個 API : https://prices.azure.com/api/retail/prices
,返回的資料結構 :
{
"BillingCurrency":"USD",
"CustomerEntityId":"Default",
"CustomerEntityType":"Retail",
"Items":[
{
"currencyCode":"USD",
"tierMinimumUnits":0.0,
"retailPrice":10.56,
"unitPrice":10.56,
"armRegionName":"uksouth",
"location":"UK South",
"effectiveStartDate":"2018-11-01T00:00:00Z",
"meterId":"0001d427-82df-4d83-8ab2-b60768527e08",
"meterName":"E10 Disks",
"productId":"DZH318Z0BP88",
"skuId":"DZH318Z0BP88/001V",
"productName":"Standard SSD Managed Disks",
"skuName":"E10 LRS",
"serviceName":"Storage",
"serviceId":"DZH317F1HKN0",
"serviceFamily":"Storage",
"unitOfMeasure":"1/Month",
"type":"Consumption",
"isPrimaryMeterRegion":true,
"armSkuName":""
}
],
"NextPageLink":"https://prices.azure.com:443/api/retail/prices?$skip=100",
"Count":100
}
因為 Azure 上服務太多
了,資料量太大,所以此 API 每個請求只能返回 100
筆資料,並提供 NextPageLink
屬性給下 100 筆資料的 URL
。
藉此筆者這邊簡單寫一個 C# 下載腳本,如下
大約完整下載需要一段時間,所以提供抓完的資料 : 2020-10-12-AzurePrices.json (79MB,135101筆資料) 給讀者參考。
void Main()
{
var client = new HttpClient();
var list = new List<Price>();
var i = 0;
while(true))
{
var url = $"https://prices.azure.com/api/retail/prices?$skip={i*100}";
var content = client.GetStringAsync(url).Result;
var data = JsonConvert.DeserializeObject<Retail>(content);
// 如果沒有下100資料,NextPageLink 會是 null,停止繼續分析
// e.g : {"BillingCurrency":"USD","CustomerEntityId":"Default","CustomerEntityType":"Retail","Items":[],"NextPageLink":null,"Count":0}
if(data.NextPageLink == null)
break;
list.AddRange(data.Items);
i++;
Console.WriteLine(i);
}
//將結果保存到
var path = Path.Combine(GetDownloadFolderPath(),"AzurePrices.json");
File.WriteAllText(path,JsonConvert.SerializeObject(list));
}
string GetDownloadFolderPath()
{
return Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "{374DE290-123F-4565-9164-39C4925E467B}", String.Empty).ToString();
}
public class Price
{
public string currencyCode { get; set; }
public double tierMinimumUnits { get; set; }
public double retailPrice { get; set; }
public double unitPrice { get; set; }
public string armRegionName { get; set; }
public string location { get; set; }
public DateTime effectiveStartDate { get; set; }
public string meterId { get; set; }
public string meterName { get; set; }
public string productId { get; set; }
public string skuId { get; set; }
public string productName { get; set; }
public string skuName { get; set; }
public string serviceName { get; set; }
public string serviceId { get; set; }
public string serviceFamily { get; set; }
public string unitOfMeasure { get; set; }
public string type { get; set; }
public bool isPrimaryMeterRegion { get; set; }
public string armSkuName { get; set; }
public string reservationTerm { get; set; }
}
public class Retail
{
public string BillingCurrency { get; set; }
public string CustomerEntityId { get; set; }
public string CustomerEntityType { get; set; }
public List<Price> Items { get; set; }
public string NextPageLink { get; set; }
public int Count { get; set; }
}
接著轉成 csv 的腳本,這邊有提供放在 Github 已轉好檔案 2020-10-12-AzurePrices.xlsx
void Main()
{
var path = @"azure json Prices Json 路徑";
var json = File.ReadAllText(path);
var dt = JsonConvert.DeserializeObject<DataTable>(json);
dt.WriteToCsvFile(@"C:\Users\HanYang\Downloads\AzurePrices.csv");
}
public static class DataTableExtensions
{
public static void WriteToCsvFile(this DataTable dataTable, string filePath)
{
StringBuilder fileContent = new StringBuilder();
foreach (var col in dataTable.Columns)
{
fileContent.Append(col.ToString() + ",");
}
fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
foreach (DataRow dr in dataTable.Rows)
{
foreach (var column in dr.ItemArray)
{
fileContent.Append("\"" + column.ToString() + "\",");
}
fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
}
System.IO.File.WriteAllText(filePath, fileContent.ToString());
}
}
接著就能做查詢動作 :
舉例 : 想知道 app service 所有區域價格低到高
方式 : 轉成 filter 模式 > 將 serviceName 篩選 Azure App Service
> unitPrice 選擇正序排序
方式 : 在armRegionName
filter 就可以看到那些地區有支援